{
	name:"FunctionTool",
	importCommand:[{
		key:"FuncDataGet",
		path:'./paint_plugin/function-picker/func-data-get'
	},{
		key:"FunctionPicker",
		path:'./paint_plugin/function-picker'
	},{
		key:'{Letter,Plugin,Web}',
		path:'./config'
	},{
		key:"Tool",
		path:"./paint_tool/function.shape"
	},{
		key:"BaseEditMX",
		path:"./paint_tool/base-edit.mx"
	}],
	onInit(){
		console.log("func")
		this.letters = Letter.capital
		this.toolInstances = this.$env.get("toolInstances")
		this.functionPicker = new FunctionPicker(this.$event,this.$env)
		this.CacheFuncData = new Map()
		this.CacheFuncDataGhost = new Map()
		this.$env.set(Cst.CacheFuncData,this.CacheFuncData)
		this.$env.set(Cst.CacheFuncDataGhost,this.CacheFuncDataGhost)
		this.mixin([BaseEditMX])
		this.init()

		this.bind()
	},
	bind(){
		this.$event.on(EN.resize,this.updateCacheFuncData.bind(this))
		this.$event.on(EN.scaleAnimate,this.doScaleCacheData.bind(this))
		this.functionPicker.on(EN.input_done,this.onInputDone.bind(this))
		this.functionPicker.on(EN.onLeftItemFocus,this.onPathFocusByID.bind(this))
		
		this.$version.on(EN.commit,(steps)=>{
			if(!this.active)return
			this.functionPicker.updateCache(steps[0],true)
		})
		this.$version.on(EN.update,(step)=>{
			if(!this.active)return
			this.functionPicker.updateCache(step)
		})
		this.$version.on(EN.remove,(ids)=>{
			if(!this.active)return 
			this.functionPicker.removeItems(ids)
		})
		this.on(EN.pathFocus,(ids)=>{
			this.functionPicker.focusItems(ids)
		})
	},
	doScaleCacheData(pr,r,done){
		let cfd = this.CacheFuncData
		let cfdg = this.CacheFuncDataGhost
		for(let [k,v] of cfdg){
			v.forEach((ps,i1)=>{
				ps.forEach((p,i2)=>{
					let isob = Object.isObject(p)
					let ps1 = isob?[p]:p
					ps1.forEach((d,i3)=>{
						let dorigin = cfd.get(k)[i1][i2]
						dorigin = isob?dorigin:dorigin[i3]
						let {x,y} = dorigin
						let nx = x*r/pr
						let ny = y*r/pr
						d.x=nx
						d.y=ny
						if(done){
							dorigin.x = nx
							dorigin.y = ny
						}
					})
				})
			})
		}
		if(done)
			this.updateCacheFuncData()
	},
	updateCacheFuncData(){
		let pageRect = document.pageRect()
		let translate = $env.get("translate")
		let cfd = this.CacheFuncData
		let cfdg = this.CacheFuncDataGhost
		cfd.clear()
		cfdg.clear()
		let fns = this.$version.queryByAction(Action.FunctionTool)
		let watchers = fns.length
		fns.forEach(stepData=>{
			let {step,state} = stepData
			let ratio = state.ratio*state.zoom
			let stepMeta = step[0]
			FuncDataGet.createDataByInputAsync(stepMeta,pageRect,translate,ratio)
			.then((rs)=>{
				cfd.set(stepMeta.raw,rs)
				cfdg.set(stepMeta.raw,rs.clone())
				watchers--
				if(watchers===0)
					this.$event.emit(EN.reapint)
			})	
		})
	},
	draw(stepData,context){
		let ps = []
		let $env = this.$env
		let cfd =  this.CacheFuncData
		let cfdg = this.CacheFuncDataGhost
		let {step,state} = stepData
		let pageRect = document.pageRect()
		let translate = $env.get("translate")
		let ratio = state.ratio*state.zoom
		let stepMeta = step[0]
		// let mode = $env.get("mode")
		let cachePs = cfdg.get(stepMeta.raw)
		if(!cachePs)
		FuncDataGet.createDataByInputAsync(stepMeta,pageRect,translate,ratio)
		.then((rs)=>{
			rs.forEach((p)=>{
				this.tool.draw({
					step:p,state,type:stepMeta.arg
				},context||this.ghostCtx)
			})
			cfd.set(stepMeta.raw,rs)
			cfdg.set(stepMeta.raw,rs.clone())
		})	
		else
		cachePs.forEach((p)=>{
			this.tool.draw({
				step:p,state,type:stepMeta.arg
			},context||this.ghostCtx)
		})
	},
	onInputDone(data,save){
		if(!this.active)return
		if(data.id)
			this.onUpdate(data,save)
		else 
			this.onCreate(data,save)
	},
	onCreate(r,save){
		try{
			let stepData ={
				step:[r],
				state:this.getContextState()
			}
			this.clearRect()
			this.draw(stepData)
			if(save){
				this.clearRect()
				this.$version.commit(Action.FunctionTool,stepData)
			}
		}catch(e){
			console.error(e)
		}
	},
	onUpdate(r,save){
		if(!this.active)return
		this.clearRect()
		let {state,step,id} = r
		if(save)
			this.$version.commit(Action.FunctionTool,{state,step},id)
		if(state.visible)
			this.pathFocus(r)
	},
	loadFnsInVersion(){
		return this.$version.queryByAction(Action.FunctionTool,s=>true).reverse()
	},
	onFocusIn(nav){
		this.$event.emit(EN.requestLeftPanel,nav.assign({id:Plugin.func}))
		this.functionPicker.focusIn(this.loadFnsInVersion())
	},
	onFocusOut(){
		this.ghostCtx.pathMode = false
		this.functionPicker.focusOut()
	}
}